package cn.xuan.zp.service.log.aop;

import cn.xuan.zp.service.log.bo.IBusinessLogger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;

@Aspect
@Component
public class LogAopAction {
    private static final Logger LOGGER = LoggerFactory.getLogger(LogAopAction.class);
    @Autowired
    private IBusinessLogger business;

    @Pointcut("@annotation(cn.xuan.zp.service.log.Annotation.LogAnnotation)")
    private void pointCutMethod() {
    }

    //声明该方法为一个前置通知:在目标方法开始之前执行
    //execution中是AspectJ表达式
//    @Before(value = "execution(* com.hnzgjt.www.web.**.**.*(..))")
    @Before(value = "pointCutMethod()")
    public void beforeMethod(JoinPoint joinPoint){

    	LOGGER.info("LogAopAction.beforeMethod");
    	if(isCan()){
            business.before(joinPoint);
        }
    }
    //后置通知，就是在目标方法执行之后（无论是否发生异常）执行的通知
    //后置通知中不能访问目标方法的返回结果
//    @After(value = "execution(* com.hnzgjt.www.web.**.**.*(..))")
    @After(value = "pointCutMethod()")
    public void afterMethod(JoinPoint joinPoint){

    	LOGGER.info("LogAopAction.afterMethod");
        if(isCan()){
            business.before(joinPoint);
        }
    }

    //返回通知，在方法正常结束之后执行的代码
    //返回通知是可以访问到方法的返回值的
//    @AfterReturning(value = "execution(* com.hnzgjt.www.web.**.**.*(..))",returning = "result")
    @AfterReturning(value = "pointCutMethod()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){

    	LOGGER.info("LogAopAction.afterReturning");
        if(isCan()){
            business.afterReturn(joinPoint,result);
        }
    }


    /**
     * 记录操作日志
     */
    @AfterThrowing(pointcut = "pointCutMethod()", throwing = "ex")  // 使用上面定义的切入点
    public void recordLog(JoinPoint joinPoint, Exception ex) {
    	LOGGER.info("LogAopAction.recordLog");
        if(isCan()){
            business.throwing(joinPoint,ex);
        }
    }

    public IBusinessLogger getBusiness() {
        return business;
    }

    public void setBusiness(IBusinessLogger business) {
        this.business = business;
    }
/*public static IBusinessLogger getBusiness() {
        return business;
    }

    public static void setBusiness(IBusinessLogger business) {
        business = business;
    }*/

    private boolean isCan(){
        return null != business;
    }
}
